<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      .list-wrapper {
        width: 400px;
        height: 400px;
        background: blue;
        user-select: none;
        overflow-y: scroll;
      }
      .list-item {
        height: 100PX;
        border-bottom: 1px solid #fff;
      }
      .load-text {
        background: red;
        height: 50px;
        line-height: 50px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div class="list-wrapper" ref="listWrapper" @scroll.passive="fnScroll">
        <div class="load-text" v-show="isRefresh">刷新中... </div>
        <ul class="list-content" ref="listContent">
          <li v-for="(item, index) in listData" :key="index" class="list-item">
            {{item}}
          </li>
        </ul>
        <div class="load-text" v-show="isLoad">加载中... </div>
      </div>
    </div>
  </body>
</html>
<script src="vue.min.js"></script>
<script src="lodash.min.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      initTop: 0,
      listData: [],
      isRefresh: false,
      isLoad: false,
      fnScroll: () => {},
    },
    mounted() {
      this.$nextTick(() => {
        this.getList(); // 初始化数据
        this.refreshData(); // 在顶部时下拉刷新数据
        this.fnScroll = _.throttle((ev) => { // 滚动到底部时，加载更多，需要处理节流问题
          this.scrollLoad(ev)
        }, 1000)
      })
    },
    methods: {
      refreshData() {
        var oTag = this.$refs.listWrapper;
        var disX = 0;
        var disY = 0;
        var t = 0;
        var that = this;
        oTag.onmousedown = function(ev) {
          var oEvent = ev || event;
          disX = oEvent.clientX;
          disY = oEvent.clientY;
          oTag.onmousemove = function(ev) {
            var oEvent = ev || event;
            t = oEvent.clientY - disY;
            if (t > 0 && t > 20) {
              that.isRefresh = true;
            }
          };
          oTag.ononmouseout = oTag.onmouseup = function() {
            oTag.onmousemove = null;
            oTag.onmouseup = null;
            that.isRefresh = false;
            if (t > 0 && that.initTop == 0) { // that.initTop == 0 必须在顶部时，才能下拉刷新
              that.getList();
            }
          };
          return false; //chrome、ff、IE9
        };
      },
      scrollLoad(ev) {
        var that = this;
        const boxElement = ev.target;
        var boxScrollpositionHeight = boxElement.offsetHeight;
        var scrollcurHeight = boxElement.scrollTop;
        var scrollTop = scrollcurHeight;
        var scroll = scrollTop - this.initTop
        this.initTop = scrollTop;
        if (scroll > 0) { // 这一层的判断不能少，判断其是向上向下滚动
          if (scrollcurHeight + boxElement.clientHeight >= (boxElement.scrollHeight - 10)) {
            console.log("滚动到底部了", )
            that.isLoad = true;
            that.getList('load');
          }
        }
      },
      getList(type) {
        var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14];
        if (type && type == 'load') {
          this.listData = [...this.listData, ...arr]; // 前后顺序不要错了
        } else {
          this.listData = arr;
        }
      }
    }
  });
</script>
